package main

import (
	"fmt"
	"log/slog"
	"math/big"
	"raymond/api/bnb"
	"raymond/api/common"
	"raymond/api/tron"
	"raymond/biz/schedule"
	"raymond/biz/transfer"
	"raymond/contract"
	"raymond/demo"
	"raymond/global"
	"raymond/result"
	"time"

	"github.com/go-playground/validator/v10"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"github.com/tidwall/gjson"
	"gopkg.in/natefinch/lumberjack.v2"
)

func main() {
	out_env()

	// 用于调试场景,临时使用
	/*
		tempLogFilename := global.GetTempLogfilepath()
		logFile, err := os.OpenFile(tempLogFilename, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
		if err != nil {
			fmt.Println("App start Failed", err)
			os.Exit(1)
		}
		log.SetOutput(logFile)
		log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
	*/

	// 用于生产场景
	jackLog := &lumberjack.Logger{
		Filename:   global.GetLogfilepath(),
		MaxSize:    100,
		MaxBackups: 50,
		MaxAge:     30,
		Compress:   false,
		LocalTime:  true,
	}
	slog.SetDefault(slog.New(slog.NewTextHandler(jackLog, &slog.HandlerOptions{
		AddSource: true,
		Level:     slog.LevelDebug,
	})))

	global.InitClient()

	test_func()
	//runSchedule()
	//runServer()
}

func runServer() {
	global.DB()

	srv := echo.New()

	srv.Use(middleware.Logger())
	srv.Use(middleware.Recover())
	srv.Validator = &result.AppVolidator{Validator: validator.New()}

	srv.POST("/api/v1/generateWallet", common.GenerateWalletV1API)
	srv.POST("/api/v1/transfer/collect", transfer.TokenCollectV1API)

	srv.Logger.Fatal(srv.Start(":8081"))
}

func runSchedule() {
	schedule.Startup()
}

func out_env() {
	appAddr := global.GetAppAddr()
	bscUrl := global.GetBSCUrl()
	bscApiUrl := global.GetBSCApiUrl()
	tronEventUrl := tron.GetTrcApiEventUrl()
	tronApiUrl := tron.GetTrcApiRpcUrl()
	dbUrl := global.GetDBUrl()
	logfile := global.GetLogfilepath()
	tronContract := tron.GetTrc20ContractList()
	bnbContract := bnb.GetBep20ContractList()
	kspath := contract.GetKeystorePath()

	fmt.Println("current env", global.DEFAULT_ENV)
	fmt.Println("appAddr", appAddr)
	fmt.Println("bscUrl", bscUrl)
	fmt.Println("bscApiUrl", bscApiUrl)
	fmt.Println("tronEventUrl", tronEventUrl)
	fmt.Println("tronApiUrl", tronApiUrl)
	fmt.Println("dbUrl", dbUrl)
	fmt.Println("logfile", logfile)
	fmt.Println("bnbContract", bnbContract)
	fmt.Println("tronContract", tronContract)
	fmt.Println("localKeystorePath", kspath)
}

func test_func() {
	//out_env()
	//useContract()
	//schedule.ListenBEP20Recharge()
	useTron()
	//dynamicJson()
	// testTime()
}

func testTime() {
	var msFormat string = "2006-01-02 15:04:05.000"
	var startTimeFormatted string = "2024-04-22 08:07:00.000"

	startTime, err := time.ParseInLocation(msFormat, startTimeFormatted, time.Local)
	if err != nil {
		slog.Error("parse time failed", err)
		return
	}
	startTimestamp := startTime.In(time.Local).Unix()
	startTimeStr := startTime.Format(msFormat)

	now := time.Now().In(time.Local).Unix()
	//s = time.Unix(passedTimestamp, 0).Format(msFormat)
	nowStr := time.Unix(now, 0).Format(msFormat)
	fmt.Println(nowStr, startTimeStr)
	fmt.Println(now, startTimestamp)

	passedTimestamp := now - startTimestamp
	maintainedBlock := passedTimestamp / (3600 * 6) * 2
	passedBlockCount := passedTimestamp/3 - maintainedBlock + 20
	fmt.Println(passedTimestamp, passedBlockCount)
}

func dynamicJson() {
	//jsons := `{"status":"0","message":"NOTOK","result":"Too many invalid api key attempts, please try again later"}`
	jsons2 := `{"status":"3","message":"OK","result":[{"blockNumber":"38130844","timeStamp":"1713934166","hash":"0x818cf2aa27a47084232bbf68140dd3d13ebf8cd56bbf114f593fd47cdc6b178a","nonce":"20097","blockHash":"0xeaf62e9671946ad406e03b50ee760cc46449d75bfcc3e33431aff530ef18e30a","from":"0x5f5a7cf8d02d8c769e8e06f81a8dd8bf35249fe8","contractAddress":"0x55d398326f99059ff775485246999027b3197955","to":"0xe382fe3c9ffec36ae9536b6dba164f0675382d55","value":"0","tokenName":"Binance-Peg BSC-USD","tokenSymbol":"BSC-USD","tokenDecimal":"18","transactionIndex":"214","gas":"250000","gasPrice":"0","gasUsed":"242454","cumulativeGasUsed":"29860202","input":"deprecated","confirmations":"414"},{"blockNumber":"38130616","timeStamp":"1713933482","hash":"0x231aaae36e8eddd23260cb47ee45dd319e7d0cb9b6e583f36b084db483e85eee","nonce":"0","blockHash":"0x2c4ec756a944031ae8611336a821a7898dd7f45b69d77e44151bf63970a78067","from":"0x5f5a7cf8d02d8c769e8e06f81a8dd8bf35249fe8","contractAddress":"0x55d398326f99059ff775485246999027b3197955","to":"0xe35b02c79ad872f82c17f2a2a16b18e311382d55","value":"1500000000000000000","tokenName":"Binance-Peg BSC-USD","tokenSymbol":"BSC-USD","tokenDecimal":"18","transactionIndex":"17","gas":"34503","gasPrice":"3030000000","gasUsed":"29703","cumulativeGasUsed":"837005","input":"deprecated","confirmations":"642"},{"blockNumber":"38130255","timeStamp":"1713932399","hash":"0x3bfe2f9b20f76d4d1215676e880d73ef72eb5ec6fa1f88cd079cfc4481b86d5a","nonce":"2","blockHash":"0x541a4b742f1fbd6932126e0776397ec707d50e513fb2ea2fc76f2db69d933b7b","from":"0xe35b02c79ad872f82c17f2a2a16b18e311382d55","contractAddress":"0x55d398326f99059ff775485246999027b3197955","to":"0x5f5a7cf8d02d8c769e8e06f81a8dd8bf35249fe8","value":"500000000000000000","tokenName":"Binance-Peg BSC-USD","tokenSymbol":"BSC-USD","tokenDecimal":"18","transactionIndex":"17","gas":"60000","gasPrice":"3030000000","gasUsed":"34503","cumulativeGasUsed":"1228310","input":"deprecated","confirmations":"1003"},{"blockNumber":"38105567","timeStamp":"1713858159","hash":"0xa1843b5ff0c0390d5d173c72f38592e7a5fa9bfd136a5ed9f1fe2f3e904788ee","nonce":"1","blockHash":"0x0f6fc5ffcb5bf8717d72a600ee8b1128c58ca6ba44f0ebf7522cb63e32d71a18","from":"0xe35b02c79ad872f82c17f2a2a16b18e311382d55","contractAddress":"0x55d398326f99059ff775485246999027b3197955","to":"0x5f5a7cf8d02d8c769e8e06f81a8dd8bf35249fe8","value":"1000000000000000000","tokenName":"Binance-Peg BSC-USD","tokenSymbol":"BSC-USD","tokenDecimal":"18","transactionIndex":"21","gas":"60000","gasPrice":"3030000000","gasUsed":"51603","cumulativeGasUsed":"1598846","input":"deprecated","confirmations":"25691"}]}`
	value := gjson.Get(jsons2, "status")
	fmt.Println(value.Str == "3")
}

func useContract() {
	//testHotFudgeSauce()
	// testSimpleBank()
	// testQuery()
	// demo.TestDeployERC20()

	wallet0 := demo.GetAccount0()
	wallet1 := demo.GetAccount1()
	wallet2 := demo.GetAccount2()
	//wallet3 := demo.GetAccount3(os)

	//demo.TestERC20Post(acct0, acct1, acct2, acct3)
	//demo.TestERC20QueryBal(acct0, acct1, acct2, acct3)
	// demo.TestDeployPermit2()
	//demo.TestEcrecoverSimple()
	// demo.TestPermit2(acct0, acct0pr, acct3, acct3pr, acct2, acct2pr)
	//demo.Test712Demo(acct0pr, contract)
	demo.GetBalance(tron.GetTrc20ContractList()[0], wallet0.EthAddr, wallet1.EthAddr, wallet2.EthAddr)
	contract := ""

	txAmt := big.NewInt(100)
	// 1授权给0
	ok, tx, coinHash, err := bnb.Approve(wallet1.EthAddr, wallet1.Pr, wallet0.EthAddr, wallet0.Pr, txAmt, contract)
	if err != nil {
		fmt.Println(err)
		if !ok {
			return
		}
	} else {
		fmt.Printf("approveHash:%v, coinHash:%v\n", tx.Hash().Hex(), coinHash)
	}
	// 0将1的代币转给2
	tx, err = bnb.TransferFrom(wallet0.Pr, wallet1.EthAddr, wallet2.EthAddr, txAmt, contract)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("transferFromHash:%v\n", tx.Hash().Hex())
}

func useTron() {
	wallet0 := demo.GetAccount0() // 归集账号
	wallet1 := demo.GetAccount1() // 扣费账号
	wallet2 := demo.GetAccount2() // 平台账号
	//wallet3 := demo.GetAccount3()
	// 模拟普通归集: 扣费账号向平台账号本币用于交易,平台账号向归集账号转u
	/*
			hex, err := tron.TransferTrx(wallet0.Pr, wallet0.TronAddr, wallet2.TronAddr, 2)
			if err != nil {
				fmt.Println(err)
				return
			}
			fmt.Println("trx hex", hex)
		hex, err := tron.TransferTrc20(wallet2.Pr, wallet2.TronAddr, wallet0.TronAddr, tron.GetTrc20ContractList()[0], 2)
		if err != nil {
			fmt.Println("u err", err)
			return
		}
		fmt.Println("u hex", hex)
		bal, err := tron.GetTrc20Balance(wallet0.TronAddr, tron.GetTrc20ContractList()[0])
		if err != nil {
			fmt.Println(err)
			return
		}
		fmt.Println("acct0 bal", bal)
		bal, err = tron.GetTrc20Balance(wallet1.TronAddr, tron.GetTrc20ContractList()[0])
		if err != nil {
			fmt.Println(err)
			return
		}
		fmt.Println("acct1 bal", bal)
	*/
	err := tron.TestTransferTRC20(wallet1.TronAddr, wallet0.TronAddr, wallet2.TronAddr, 100)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("end")
}
